﻿Imports Commander_Wars.Spieletools
Imports Microsoft.DirectX.Direct3D
Imports Microsoft.DirectX
Public MustInherit Class ObjektGebaeude
    Implements ICloneable
#Region "Variablen"
    Enum Angriffe
        Keiner
        Kreis
        Strahl
        SchussN
        SchussO
        SchussS
        SchussW
        DreiStrahlN
        DreiStrahlO
        DreiStrahlS
        DreiStrahlW
        FabrikBauen
        Silo
        Rakete
        Sendeturm
        HQ
        Vulkan
        Mine
        ''' <summary>
        ''' Der Angriff der fliegenden Festung
        ''' </summary>
        ''' <remarks></remarks>
        KugelKreis
        ''' <summary>
        ''' Meint das wir einen Sichtbonus im Kriegsnebel bekommen.
        ''' </summary>
        ''' <remarks></remarks>
        Radar
        ''' <summary>
        ''' Heisst kann keine Truppen bauen! LOL
        ''' </summary>
        ''' <remarks></remarks>
        Temporaer
    End Enum
    Public Const Besetzungszahl As Byte = 20


    Private Spielern As Integer
    Public Property Spieler() As Integer
        Get
            Return Spielern
        End Get
        Set(ByVal value As Integer)
            Spielern = value
        End Set
    End Property
    Private GebaeudeIDD As String
    Public Property GebaeudeID() As String
        Get
            If GebaeudeIDD = "VERWEIS" Then
                If IsNothing(Objektverwalter.Spielfeld) = False Then
                    If Hauptmenue.Pause = False Then
                        If Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Me.Schlacht).Gebaeude IsNot Nothing Then
                            Return Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Me.Schlacht).Gebaeude.GebaeudeIDD
                        Else
                            Return GebaeudeIDD
                        End If
                    ElseIf Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Me.Schlacht).Gebaeude Is Nothing Then
                        Return GebaeudeIDD
                    Else
                        Return Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Me.Schlacht).Gebaeude.GebaeudeIDD
                    End If
                Else
                    Return GebaeudeIDD
                End If
            Else
                Return GebaeudeIDD
            End If
        End Get
        Set(ByVal value As String)
            GebaeudeIDD = value
        End Set
    End Property


    Protected Bestzunge As Integer = -1
    Public Property Besetzung() As Integer
        Get
            Return Bestzunge
        End Get
        Set(ByVal value As Integer)
            If Not Angriff = Angriffe.Silo Then
                If GebaeudeIDD <> "RAKETENSILO" Then
                    Bestzunge = value
                End If
            End If
        End Set
    End Property
    Public Function Besetzen(ByVal Einheit As ObjektEinheit) As Boolean
        If Bestzunge > 0 Then
            Objektverwalter.Spielfeld.AktuelleEinheit.Besetzen = True
            If DataSettings.BesetzungsAnimation = True And Not Hauptmenue.Aufzeichnungsspulen Then
                Objektverwalter.NeuObjektAnimation(New Point(Rechteck.X, Rechteck.Y), "BESETZEN", ObjektSpielfeld.TopLayer)
            Else
                Dim Aenderung As Integer = Einheit.getKP
                Dim Bonus As Single = Objektverwalter.Spielfeld.Spieler(Einheit.Spieler).KOS(0).Besetzer
                Dim BoostMode As Single = Einheit.GetSpieler.KOS(0).GetKOZoneBoost(Einheit)
                If Bonus <> 0 Then
                    If BoostMode = 0 Then
                        Bonus = 0
                    Else
                        Dim Bonus2 As Single = Math.Round(Bonus)
                        If Objektverwalter.Spielfeld.Regeln.KOSystem > KOSysteme.Gabe_Modus Then
                            'Wir schaue ob Addiert oder multipliziert werden soll
                            If Bonus2 = Bonus Then
                                Bonus = 1 + Math.DivRem(CInt(Bonus - 1), CInt(1 / BoostMode), 0)
                            Else
                                Bonus *= BoostMode
                            End If
                        Else
                            'Wir schaue ob Addiert oder multipliziert werden soll
                            If Bonus2 = Bonus Then
                                Bonus = CInt(Bonus)
                            End If
                        End If
                    End If
                End If
                If Not Bonus = 0 Then
                    Dim Bonus2 As Single = Math.Round(Bonus)
                    'Wir schaue ob Addiert oder multipliziert werden soll
                    If Bonus2 = Bonus Then
                        Aenderung += Bonus
                    Else
                        Aenderung *= Bonus
                    End If

                End If
                Aenderung += Einheit.BesetzungsBonus
                Dim Bonussenkung As Integer = Objektverwalter.Spielfeld.Spieler(Einheit.Spieler).KOS(0).GetBonusgebaeude(Rechteck.X, Rechteck.Y)
                If Bonussenkung >= 0 Then
                    Aenderung -= Objektverwalter.Spielfeld.Spieler(Einheit.Spieler).KOS(0).BonusGebaeude(Bonussenkung).Z
                    Objektverwalter.Spielfeld.Spieler(Einheit.Spieler).KOS(0).RemoveBonusGebaeude(Bonussenkung)
                End If
                Besetzung -= Aenderung
                If Besetzung <= 0 Then
                    Objektverwalter.Spielfeld.AktuelleEinheit.Besetzen = False
                    Bestzunge = Besetzungszahl
                    Select Case Angriff
                        Case Angriffe.HQ
                            If Spieler > 0 Then
                                Objektverwalter.Spielfeld.Aufzeichnung.AddEreignis(Spieler, Objektverwalter.Spielfeld.Runde, BesonderesEreigniss.Ereignisse.HQVerlust)
                            End If
                            Objektverwalter.Spielfeld.Aufzeichnung.AddEreignis(Einheit.Spieler, Objektverwalter.Spielfeld.Runde, BesonderesEreigniss.Ereignisse.HQEroberung)
                    End Select
                    Objektverwalter.Spielfeld.Regeln.CheckSieg()

                    Spieler = Einheit.Spieler
                    getBildID(Nothing)
                    Return True
                Else
                    Return False
                End If
                MusikEngine.LoadWav(DataSettings.Resourcenpfad + "Sound\Sound Effects\Overworld\Erobert.wav", False)
                End If
        End If
        Return False
    End Function

    Protected Leben As Integer
    Public Property KP() As Integer
        Get
            If GebaeudeIDD = "VERWEIS" Then
                Return Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Schlacht).Gebaeude.KP
            Else
                Return Leben
            End If
        End Get
        Set(ByVal value As Integer)
            Leben = value
        End Set
    End Property
    Public Function GetKP(ByVal X As Integer, ByVal Y As Integer, ByVal FuerAnzeige As Boolean) As Integer
        If FuerAnzeige Then
            If GebaeudeIDD = "VERWEIS" Then
                Return Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Schlacht).Gebaeude.KP
            Else
                Return Leben
            End If
        Else
            If IsAttackField(X, Y) Then
                If GebaeudeIDD = "VERWEIS" Then
                    Return Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Schlacht).Gebaeude.KP
                Else
                    Return Leben
                End If
            End If
        End If
        Return -1
    End Function


    Private Schade As Integer = 0
    Public Property Schaden() As Integer
        Get
            If Schade > 0 Then
                Return Schade + Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).GebaeudeZusatzSchaden
            ElseIf Schade < 0 Then
                Return Schade - Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).GebaeudeZusatzSchaden
            Else
                Return Schade
            End If
        End Get
        Set(ByVal value As Integer)
            Schade = value
        End Set
    End Property
    Private Reichweiten As Integer = -1
    Public Property Reichweite() As Integer
        Get
            Return Reichweiten
        End Get
        Set(ByVal value As Integer)
            Reichweiten = value
        End Set
    End Property
    Protected Feuerbereite As Integer


    ''' <summary>
    '''  Negative Werte setzen die Zahl auf das Maximum
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Feuerbereit() As Integer
        Get
            Return Feuerbereite
        End Get
        Set(ByVal value As Integer)
            If value < 0 Then
                Feuerbereite = Feuerladung
            Else
                Feuerbereite -= value
            End If
            If Feuerbereite < 0 And Feuerladung > 0 Then
                Feuerbereite = 0
            End If
        End Set
    End Property
    Public Sub SetFeuerbereit(ByVal Feuerbereit As Integer)
        Feuerbereite = Feuerbereit
    End Sub
    Structure Variable
        Implements ICloneable
        Public Sub New(ByVal Name As String, ByVal Wert As Integer)
            Namen = Name
            Werte = Wert
        End Sub
        Private Namen As String
        Public Property Name() As String
            Get
                Return Namen
            End Get
            Set(ByVal value As String)
                Namen = value
            End Set
        End Property
        Private Werte As Integer
        Public Property Wert() As Integer
            Get
                Return Werte
            End Get
            Set(ByVal value As Integer)
                Werte = value
            End Set
        End Property
        Public Function Clone() As Object Implements System.ICloneable.Clone
            Return MemberwiseClone()
        End Function
        Public Sub Write(ByRef StrW As Filestream)
            WriteString(StrW, Namen)
            Dim B(3) As Byte
            B = IntToBytes(Werte)
            For I = 0 To B.Length - 1
                StrW.WriteByte(B(I))
            Next
        End Sub
        Public Sub read(ByRef StrR As Filestream)
            Namen = ReadString(StrR)
            Dim B(3) As Byte
            For I = 0 To B.Length - 1
                B(I) = StrR.ReadByte
            Next
            Werte = BytesToInt(B)
        End Sub

    End Structure
    Public Variablen As Variable() = {}
    Public Verweisgebaeude(,) As Integer = {}
    Protected Verfonds As Boolean = False
    Public Property Versorung() As Boolean
        Get
            Return Verfonds
        End Get
        Set(ByVal value As Boolean)
            Verfonds = value
        End Set
    End Property
    Private Deckunge As Integer
    Public Property Deckung() As Integer
        Get
            Return Deckunge
        End Get
        Set(ByVal value As Integer)
            Deckunge = value
        End Set
    End Property
    Public WirdZu As String = ""
    Private getFond As Boolean = False
    Public Property getFonds() As Boolean
        Get
            Return getFond
        End Get
        Set(ByVal value As Boolean)
            getFond = value
        End Set
    End Property
    Private Gebaeudenamen As String
    Public Property Gebaeudename() As String
        Get
            If GebaeudeIDD = "VERWEIS" Then
                Return Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Me.Schlacht).Gebaeude.Gebaeudename
            Else
                Return Gebaeudenamen
            End If
        End Get
        Set(ByVal value As String)
            Gebaeudenamen = value
        End Set
    End Property
    ''' <summary>
    ''' Wenn wir das fuer die KI hier abspeichern, ist sie schneller
    ''' </summary>
    ''' <remarks></remarks>
    Public CanMoveAfterBuilding As List(Of Variable)
    Public Rechteck As Rectangle
    Public RotationsZenturm As Point
    Public Feuerladung As Integer
    Protected Schlacht As Integer
    Private BildIDD As Integer
    Public Property BildID() As Integer
        Get
            Return BildIDD
        End Get
        Set(ByVal value As Integer)
            BildIDD = value
        End Set
    End Property
    Private Angrifn As Angriffe = Angriffe.Keiner
    Public Property Angriff() As Angriffe
        Get
            Return Angrifn
        End Get
        Set(ByVal value As Angriffe)
            Angrifn = value
        End Set
    End Property
    Private Frames As Integer
    Public Property Frame() As Integer
        Get
            If Frames > 1 Then
                Return 1
            Else
                Return 0
            End If
        End Get
        Set(ByVal value As Integer)
            Frames += 1
            If Frames > 3 Then
                Frames = 0
            End If
        End Set
    End Property
#End Region
#Region "Save and Load"
    Public Sub Write(ByRef StrW As Filestream, ByVal X As Integer, ByVal Y As Integer, ByVal Schlacht As Integer, ByVal Gebaeude As List(Of String))
        'Default Values
        Dim B(3) As Byte
        B = IntToBytes(X)
        For i = 0 To B.Length - 1
            StrW.WriteByte(B(i))
        Next
        B = IntToBytes(Y)
        For i = 0 To B.Length - 1
            StrW.WriteByte(B(i))
        Next
        StrW.WriteByte(Schlacht)
        StrW.WriteByte(Gebaeude.IndexOf(GebaeudeIDD))
        B = IntToBytes(Spielern)
        For i = 0 To B.Length - 1
            StrW.WriteByte(B(i))
        Next
        If TypeOf Me Is GebaeudeVulkan Then
            WriteV16(StrW)
        Else
            If Bestzunge > 0 Then
                If 0 < Leben Then
                    If Schade <> 0 Or Reichweiten > 0 Or Feuerbereite > 0 Then
                        If Variablen.Length > 0 Then
                            WriteV0(StrW)
                        Else
                            WriteV1(StrW)
                        End If
                    Else
                        If Variablen.Length > 0 Then
                            WriteV2(StrW)
                        Else
                            WriteV3(StrW)
                        End If
                    End If
                Else
                    If Schade <> 0 Or Reichweiten > 0 Or Feuerbereite > 0 Then
                        If Variablen.Length > 0 Then
                            WriteV4(StrW)
                        Else
                            WriteV5(StrW)
                        End If
                    Else
                        If Variablen.Length > 0 Then
                            WriteV6(StrW)
                        Else
                            WriteV7(StrW)
                        End If
                    End If
                End If
            Else
                If 0 < Leben Then
                    If Schade <> 0 Or Reichweiten > 0 Or Feuerbereite > 0 Then
                        If Variablen.Length > 0 Then
                            WriteV8(StrW)
                        Else
                            WriteV9(StrW)
                        End If
                    Else
                        If Variablen.Length > 0 Then
                            WriteV10(StrW)
                        Else
                            WriteV11(StrW)
                        End If
                    End If
                Else
                    If Schade <> 0 Or Reichweiten > 0 Or Feuerbereite > 0 Then
                        If Variablen.Length > 0 Then
                            WriteV12(StrW)
                        Else
                            WriteV13(StrW)
                        End If
                    Else
                        If Variablen.Length > 0 Then
                            WriteV14(StrW)
                        Else
                            WriteV15(StrW)
                        End If
                    End If
                End If
            End If
        End If
    End Sub
    Private Sub WriteV0(ByRef StrW As Filestream)
        StrW.WriteByte(0)
        StrW.WriteByte(Bestzunge)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV1(ByRef StrW As Filestream)
        StrW.WriteByte(1)
        StrW.WriteByte(Bestzunge)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
    End Sub
    Private Sub WriteV2(ByRef StrW As Filestream)
        StrW.WriteByte(2)
        StrW.WriteByte(Bestzunge)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV3(ByRef StrW As Filestream)
        StrW.WriteByte(3)
        StrW.WriteByte(Bestzunge)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
    End Sub
    Private Sub WriteV4(ByRef StrW As Filestream)
        StrW.WriteByte(4)
        StrW.WriteByte(Bestzunge)
        Dim B(3) As Byte
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV5(ByRef StrW As Filestream)
        StrW.WriteByte(5)
        StrW.WriteByte(Bestzunge)
        Dim B(3) As Byte
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
    End Sub
    Private Sub WriteV6(ByRef StrW As Filestream)
        StrW.WriteByte(6)
        StrW.WriteByte(Bestzunge)
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV7(ByRef StrW As Filestream)
        StrW.WriteByte(7)
        StrW.WriteByte(Bestzunge)
    End Sub
    Private Sub WriteV8(ByRef StrW As Filestream)
        StrW.WriteByte(8)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV9(ByRef StrW As Filestream)
        StrW.WriteByte(9)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
    End Sub
    Private Sub WriteV10(ByRef StrW As Filestream)
        StrW.WriteByte(10)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV11(ByRef StrW As Filestream)
        StrW.WriteByte(11)
        Dim B(3) As Byte
        B = IntToBytes(Leben)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
    End Sub
    Private Sub WriteV12(ByRef StrW As Filestream)
        StrW.WriteByte(12)
        Dim B(3) As Byte
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV13(ByRef StrW As Filestream)
        StrW.WriteByte(13)
        Dim B(3) As Byte
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Feuerbereite)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
    End Sub
    Private Sub WriteV14(ByRef StrW As Filestream)
        StrW.WriteByte(14)
        For I = 0 To Variablen.Length - 1
            Variablen(I).Write(StrW)
        Next
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
        StrW.WriteByte(254)
    End Sub
    Private Sub WriteV15(ByRef StrW As Filestream)
        StrW.WriteByte(15)
    End Sub
    Private Sub WriteV16(ByRef StrW As Filestream)
        StrW.WriteByte(16)
        Dim B(3) As Byte
        B = IntToBytes(Schade)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = IntToBytes(Reichweiten)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        B = SingletoBytes(CType(Me, GebaeudeVulkan).FeuerbrockenProzent)
        For I = 0 To B.Length - 1
            StrW.WriteByte(B(I))
        Next
        WriteVec3Array(StrW, CType(Me, GebaeudeVulkan).Targets.ToArray)
    End Sub
    Public Shared Sub Read(ByRef StrR As Filestream, ByVal Spielfeld As ObjektSpielfeld, ByVal Gebaeude As String())
        'Default Values
        Dim B(3) As Byte
        For I = 0 To B.Length - 1
            B(I) = StrR.ReadByte
        Next
        Dim X As Integer = BytesToInt(B)
        For I = 0 To B.Length - 1
            B(I) = StrR.ReadByte
        Next
        Dim Y As Integer = BytesToInt(B)
        Dim Schlacht As Integer = StrR.ReadByte
        Dim ID As String = Gebaeude(StrR.ReadByte)
        For I = 0 To B.Length - 1
            B(I) = StrR.ReadByte
        Next
        Dim Spieler As Integer = BytesToInt(B)
        Dim G As ObjektGebaeude = ObjektLadeklasse.NewGebaeude(ID, Spieler, X, Y, Schlacht, Spielfeld)
        'Special Values
        Select Case StrR.ReadByte
            Case 0
                G.Bestzunge = StrR.ReadByte
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 1
                G.Bestzunge = StrR.ReadByte
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
            Case 2
                G.Bestzunge = StrR.ReadByte
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 3
                G.Bestzunge = StrR.ReadByte
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
            Case 4
                G.Bestzunge = StrR.ReadByte
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 5
                G.Bestzunge = StrR.ReadByte
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
            Case 6
                G.Bestzunge = StrR.ReadByte
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 7
                G.Bestzunge = StrR.ReadByte
            Case 8
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 9
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
            Case 10
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 11
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Leben = BytesToInt(B)
            Case 12
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 13
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Feuerbereite = BytesToInt(B)
            Case 14
                Dim Ende() As Byte = {0, 0, 0, 0}
                While Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254)
                    Ende(0) = StrR.ReadByte
                    Ende(1) = StrR.ReadByte
                    Ende(2) = StrR.ReadByte
                    Ende(3) = StrR.ReadByte
                    StrR.Seek(-4)
                    If Not (Ende(0) = 254 And Ende(1) = 254 And Ende(2) = 254 And Ende(3) = 254) Then
                        Array.Resize(G.Variablen, G.Variablen.Length + 1)
                        G.Variablen(G.Variablen.Length - 1) = New Variable
                        G.Variablen(G.Variablen.Length - 1).read(StrR)
                    End If
                End While
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
                StrR.ReadByte()
            Case 15
            Case 16
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Schade = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                G.Reichweiten = BytesToInt(B)
                For I = 0 To B.Length - 1
                    B(I) = StrR.ReadByte()
                Next
                CType(G, GebaeudeVulkan).FeuerbrockenProzent = BytesToSingle(B)
                CType(G, GebaeudeVulkan).Targets = ReadVec3Array(StrR).ToList
        End Select
        Spielfeld.Landschaften(X, Y, Schlacht).Gebaeude = G
    End Sub
#End Region

    Public Sub New(ByVal neuGebaeudeID As String, ByVal neuSpieler As Integer, ByVal neuX As Integer, ByVal neuY As Integer, ByVal Schlacht As Integer)
        Rechteck.X = neuX
        Rechteck.Y = neuY
        Spieler = neuSpieler
        GebaeudeID = neuGebaeudeID
        Me.Schlacht = Schlacht
    End Sub
    Public Sub New(ByVal neuGebaeudeID As String, ByVal neuSpieler As Integer, ByVal neuLeben As Integer, ByVal neuBesetzungszahl As Integer, ByVal neuX As Integer, ByVal neuY As Integer, ByVal Feuerzahl As Integer, ByVal Schlacht As Integer)
        Rechteck.X = neuX
        Rechteck.Y = neuY
        Spieler = neuSpieler
        GebaeudeID = neuGebaeudeID
        Bestzunge = neuBesetzungszahl
        Me.Feuerbereite = Feuerzahl
        Me.Schlacht = Schlacht
    End Sub



    Public Sub getBildID(ByVal Spielfeld As ObjektSpielfeld)
        BildIDD = -1
        If Spielfeld Is Nothing Then
            If Not Objektverwalter.Spielfeld Is Nothing Then
                If Rechteck.Width = Hauptmenue.Feldbreite And Rechteck.Height = Hauptmenue.Feldbreite * 2 Then
                    For I = 0 To Objektverwalter.AlleGebaeude.Length - 1
                        If Objektverwalter.AlleGebaeude(I).GebaeudeID = GebaeudeID Then
                            BildID = I
                            Exit For
                        End If
                    Next
                Else
                    For I = 0 To Objektverwalter.AlleGebaeude.Length - 1
                        If Objektverwalter.AlleGebaeude(I).GebaeudeID = GebaeudeID Then
                            BildID = I
                            Exit For
                        End If
                    Next
                End If
            Else
                BildIDD = -1
            End If
        Else
            For I = 0 To Objektverwalter.AlleGebaeude.Length - 1
                If Objektverwalter.AlleGebaeude(I).GebaeudeID = GebaeudeID Then
                    BildID = I
                    Exit For
                End If
            Next
        End If
        Frames = Zufallszahl(0, 3)
    End Sub
    Public MustOverride Function GetLandschaftsuntergrund() As String()
    Public MustOverride Sub DOSpielFrame()
    Public MustOverride Function GetAngriffsFelder() As Point()
    Public Overridable Function GetBauliste() As String()
        Return New String() {}
    End Function
    Public Function GetBauliste(ByVal Spieler As Integer) As String()
        Dim S As New Stack(Of String)
        Dim S1() As String = GetBauliste()
        For Each Unit In S1
            If Spieler > 0 Then
                If Objektverwalter.Spielfeld.Spieler(Spieler).SpielerBaublockade IsNot Nothing Then
                    If Objektverwalter.Spielfeld.Spieler(Spieler).SpielerBaublockade.CanBuildUnit(Unit) Then
                        If Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste.GetWert(Unit) >= 0 Then
                            S.Push(Unit)
                        End If
                    End If
                Else
                    If Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste.GetWert(Unit) >= 0 Then
                        S.Push(Unit)
                    End If
                End If
            Else
                S.Push(Unit)
            End If
        Next
        Array.Resize(S1, S.Count)
        For I = 0 To S1.Length - 1
            S1(I) = S(S.Count - I - 1)
        Next
        Return S1
    End Function
    Public Function GetBaulisteThisPlayer() As String()
        Dim S As New Stack(Of String)
        Dim S1() As String = GetBauliste()
        For Each Unit In S1
            If Spieler > 0 Then
                If Objektverwalter.Spielfeld.Spieler(Spieler) IsNot Nothing Then
                    If Objektverwalter.Spielfeld.Spieler(Spieler).SpielerBaublockade IsNot Nothing Then
                        If Objektverwalter.Spielfeld.Spieler(Spieler).SpielerBaublockade.CanBuildUnit(Unit) Then
                            If Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste.GetWert(Unit) >= 0 Then
                                S.Push(Unit)
                            End If
                        End If
                    Else
                        If Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste Is Nothing Then
                            S.Push(Unit)
                        Else
                            If Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste.GetWert(Unit) >= 0 Then
                                S.Push(Unit)
                            End If
                        End If
                    End If
                Else
                    S.Push(Unit)
                End If
            End If
        Next
        Array.Resize(S1, S.Count)
        For I = 0 To S1.Length - 1
            S1(I) = S(S.Count - I - 1)
        Next
        Return S1
    End Function
    Public Sub Malen(ByVal Kriegsnebel As Nebelarten, ByVal Alpha As Integer, ByVal KooX As Integer, ByVal KooY As Integer)
        If DataSettings.draw3D Then
            If GebaeudeIDD = "VERWEIS" Then
                Exit Sub
            End If
            ObjektLadeklasse.Gebaeude3D.Malen(GebaeudeID, KooX, KooY, Schlacht, Spieler)

        ElseIf DataSettings._2D_3D_Malen Then
            If BildID >= 0 Then
                If GebaeudeIDD = "VERWEIS" Then
                    BildIDD = -1
                    Exit Sub
                End If
                Dim intColor As Color = Color.FromArgb(Alpha, 255, 255, 255)
                Select Case Kriegsnebel
                    Case Nebelarten.Kriegsnebel, Nebelarten.Aufklaerungsnebel
                        intColor = Color.FromArgb(Alpha, 120, 120, 120)
                    Case Else
                        intColor = Color.FromArgb(Alpha, 255, 255, 255)
                End Select

                Dim cube(3) As CustomVertex.PositionTextured

                Dim MittelPunkt As Point = RotationsZenturm
                Dim XPlus As Single = -MittelPunkt.X / Hauptmenue.Feldbreite
                Dim YPlus As Single = -(Rechteck.Height - MittelPunkt.Y) / Hauptmenue.Feldbreite
                If Rechteck.Width = Hauptmenue.Feldbreite And Rechteck.Height = Hauptmenue.Feldbreite * 2 Then
                    YPlus += 0.5
                End If

                Dim Breite As Single = (Rechteck.Width) / Hauptmenue.Feldbreite
                Dim Hoehe As Single = (Rechteck.Height) / Hauptmenue.Feldbreite
                For X = 0 To Breite - 1
                    For Y = 0 To Hoehe - 1
                        cube(0) = New CustomVertex.PositionTextured(0, 0, 0, 0.5 * (Frame + X / Breite), (Hoehe - Y - 1) / Hoehe + 1 / Hoehe)
                        cube(1) = New CustomVertex.PositionTextured(0, 0, 1, 0.5 * (Frame + X / Breite), (Hoehe - Y - 1) / Hoehe)
                        cube(2) = New CustomVertex.PositionTextured(1, 0, 0, 0.5 * (Frame + X / Breite + 1 / Breite), (Hoehe - Y - 1) / Hoehe + 1 / Hoehe)
                        cube(3) = New CustomVertex.PositionTextured(1, 0, 1, 0.5 * (Frame + X / Breite + 1 / Breite), (Hoehe - Y - 1) / Hoehe)

                        If Kriegsnebel = Nebelarten.Kriegsnebel Then
                            'Wir sehen alles Neutral
                            Objektverwalter.AlleGebaeude(BildID).DrawGebaeude(0, GetSpieler.Armee, intColor, cube, ObjektSpielfeld.CalcDraw2D3DVec(KooX + XPlus + 0.5 + X, ObjektSpielfeld.SpielfeldLayer.Gebaeude, KooY - YPlus - 0.5 - Y))
                        Else
                            Objektverwalter.AlleGebaeude(BildID).DrawGebaeude(Spieler, GetSpieler.Armee, intColor, cube, ObjektSpielfeld.CalcDraw2D3DVec(KooX + XPlus + 0.5 + X, ObjektSpielfeld.SpielfeldLayer.Gebaeude, KooY - YPlus - 0.5 - Y))
                        End If

                    Next
                Next

            End If
        Else

            If BildID >= 0 Then
                If GebaeudeIDD = "VERWEIS" Then
                    BildIDD = -1
                    Exit Sub
                End If
                Dim sngRotation As Double = 0
                Dim intColor As Color = Color.FromArgb(Alpha, 255, 255, 255)
                Select Case Kriegsnebel
                    Case Nebelarten.Kriegsnebel, Nebelarten.Aufklaerungsnebel
                        intColor = Color.FromArgb(Alpha, 120, 120, 120)
                    Case Else
                        intColor = Color.FromArgb(Alpha, 255, 255, 255)
                End Select
                'pruefen ob wir aus den Screenbereich laufen

                'Festlegen welchen Bereich vom Bitmap wir kopieren

                'Welcher Teil der Textur soll gemalt werden Nichts bedeutet gesamtes Bild

                With Grafikengine.recBild
                    .X = Frame * Rechteck.Width : .Width = Rechteck.Width
                    .Y = 0 : .Height = Rechteck.Height
                End With
                With Grafikengine.szfScale
                    .Height = Rechteck.Height
                    .Width = Rechteck.Width
                End With
                Grafikengine.ptfRotCenter = RotationsZenturm
                If Kriegsnebel = Nebelarten.Kriegsnebel Then
                    'Wir sehen alles Neutral
                    If Rechteck.Width = Hauptmenue.Feldbreite And Rechteck.Height = Hauptmenue.Feldbreite * 2 Then
                        Grafikengine.ptfPosition = New Point(Rechteck.X * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooX, Rechteck.Y * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooY - Rechteck.Height / 4)
                        Objektverwalter.AlleGebaeude(BildID).DrawGebaeude(0, GetSpieler.Armee, intColor, sngRotation)
                    Else
                        Grafikengine.ptfPosition = New Point(Rechteck.X * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooX, Rechteck.Y * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooY)
                        Objektverwalter.AlleGebaeude(BildID).DrawGebaeude(0, GetSpieler.Armee, intColor, sngRotation)
                    End If
                Else
                    If Rechteck.Width = Hauptmenue.Feldbreite And Rechteck.Height = Hauptmenue.Feldbreite * 2 Then
                        Grafikengine.ptfPosition = New Point(Rechteck.X * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooX, Rechteck.Y * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooY - Rechteck.Height / 4)
                        Objektverwalter.AlleGebaeude(BildID).DrawGebaeude(Spieler, GetSpieler.Armee, intColor, sngRotation)
                    Else
                        Grafikengine.ptfPosition = New Point(Rechteck.X * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooX, Rechteck.Y * Hauptmenue.Feldbreite + Objektverwalter.Spielfeld.BildschirmKooY)
                        Objektverwalter.AlleGebaeude(BildID).DrawGebaeude(Spieler, GetSpieler.Armee, intColor, sngRotation)
                    End If
                End If

            End If
        End If
    End Sub
    ''' <summary>
    ''' Sucht die ID im angegebenen Array
    ''' </summary>
    ''' <param name="Spezialgebaeude"></param>
    ''' <param name="GebaeudeID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function FindSpezialGebaeudeID(ByVal Spezialgebaeude() As ObjektSpieler.SpezialGebaeude, ByVal GebaeudeID As String)
        For I = 0 To Spezialgebaeude.Length - 1
            If Spezialgebaeude(I).GebaeudeID = GebaeudeID Then
                Return I
            End If
        Next
        Return -1
    End Function

    ''' <summary>
    ''' Mal sehen welche Anti-Luftwaffe wir bauen koennen.
    ''' </summary>
    ''' <param name="Prueffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetProduceableAntiAirUnits(ByVal Prueffonds As Integer) As ObjektEinheit()
        Dim Units() As ObjektEinheit = {}
        Dim BListe As String() = GetBaulisteThisPlayer()
        For I = 0 To BListe.Length - 1
            Dim E As ObjektEinheit = ObjektLadeklasse.NewEinheit(BListe(I), Spieler, Rechteck.X, Rechteck.Y)
            If E.CanAttackAirUnits Then
                If CanBuildUnit(E, Prueffonds) Then
                    Array.Resize(Units, Units.Length + 1)
                    Units(Units.Length - 1) = E
                End If
            End If
        Next
        Return Units
    End Function
    ''' <summary>
    ''' Ueberprueft ob eine Einheit gebaut werden kann.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanBuildUnit(ByVal Einheit As ObjektEinheit) As Boolean
        Return CanBuildUnit(Einheit.EinheitenID)
    End Function
    ''' <summary>
    ''' Ueberprueft ob eine Einheit gebaut werden kann.
    ''' </summary>
    ''' <param name="EinheitenID"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanBuildUnit(ByVal EinheitenID As String) As Boolean
        If Objektverwalter.Spielfeld.Einheiten(Rechteck.X, Rechteck.Y, Objektverwalter.Spielfeld.MomentaneSchlacht) Is Nothing Then
            If Objektverwalter.Spielfeld.Spieler(Spieler).Fonds >= ObjektLadeklasse.GetEinheitenkosten(EinheitenID) * Objektverwalter.Spielfeld.Spieler(Spieler).Teurungsrate(EinheitenID, Rechteck.X, Rechteck.Y) Then
                If GetBaulisteThisPlayer.Contains(EinheitenID) Then
                    If Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste Is Nothing Then
                        Return True
                    ElseIf Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste.GetWert(EinheitenID) >= 0 Then
                        Return True
                    End If
                End If
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Ueberprueft welche Einheiten theoretisch gebaut werden koennen wenn man soviel Fonds haette
    ''' </summary>
    ''' <param name="Prueffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanBuildUnit(ByVal Einheit As ObjektEinheit, ByVal Prueffonds As Integer) As Boolean
        Return CanBuildUnit(Einheit.EinheitenID, Prueffonds)
    End Function
    ''' <summary>
    ''' Ueberprueft welche Einheiten theoretisch gebaut werden koennen wenn man soviel Fonds haette
    ''' </summary>
    ''' <param name="EinheitenID"></param>
    ''' <param name="Prueffonds"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanBuildUnit(ByVal EinheitenID As String, ByVal Prueffonds As Integer) As Boolean
        If Objektverwalter.Spielfeld.Einheiten(Rechteck.X, Rechteck.Y, Objektverwalter.Spielfeld.MomentaneSchlacht) Is Nothing Then
            If Prueffonds >= ObjektLadeklasse.GetEinheitenkosten(EinheitenID) * Objektverwalter.Spielfeld.Spieler(Spieler).Teurungsrate(EinheitenID, Rechteck.X, Rechteck.Y) Then
                If GetBaulisteThisPlayer.Contains(EinheitenID) Then
                    If Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste Is Nothing Then
                        Return True
                    ElseIf Objektverwalter.Spielfeld.Spieler(Spieler).GetBauliste.GetWert(EinheitenID) >= 0 Then
                        Return True
                    End If
                End If
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Gibt zurueck ob Infis mit diesem Gebaeude etwas tun koennen.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsBesetzung(ByVal Einheit As ObjektEinheit) As Boolean
        Return IsBesetzung(Einheit.Spieler)
    End Function
    ''' <summary>
    ''' Gibt zurueck ob Infis mit diesem Gebaeude etwas tun koennen.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsBesetzung(ByVal Spieler As Integer) As Boolean
        If Besetzung > 0 Or Angriff = Angriffe.Silo Then
            If Objektverwalter.Spielfeld.Spieler(Me.Spieler).Team <> Objektverwalter.Spielfeld.Spieler(Spieler).Team Then
                Return True
            Else
                Return False
            End If
        ElseIf Angriff = Angriffe.Silo Then
            Return True
        Else
            Return False
        End If
    End Function
#Region "Feuerradius Anzeigen"
    Public MustOverride Sub FeuerradiusAnzeigen()
    Protected Sub KreisAnzeigen(Optional ByVal Farbe As String = "Gruen")
        Dim Kreis(,) As Integer = Kreisfunktion(Reichweite)
        For X = 0 To Kreis.GetLength(0) - 1
            For Y = 0 To Kreis.GetLength(1) - 1
                If Kreis(X, Y) >= 0 Then
                    If Objektverwalter.Spielfeld.OnMap(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y) Then
                        Objektverwalter.neuMarkiertesFeld(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, Color.FromArgb(160, 255, 255, 255), Farbe)
                    End If
                End If
            Next
        Next
    End Sub
    Protected Function GetKreisFelder() As Point()
        Dim Felder As New Stack(Of Point)
        Dim Kreis(,) As Integer = Kreisfunktion(Reichweite)
        For X = 0 To Kreis.GetLength(0) - 1
            For Y = 0 To Kreis.GetLength(1) - 1
                If Kreis(X, Y) >= 0 Then
                    Dim Punkt As New Point(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
                    If Objektverwalter.Spielfeld.OnMap(Punkt.X, Punkt.Y) Then
                        Felder.Push(Punkt)
                    End If
                End If
            Next
        Next
        Return Felder.ToArray
    End Function
    ''' <summary>
    ''' Gibt alle Ziele zurueck auf denen eine Einheit steht die getroffen werden kann.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function KreisZiele() As Point()
        Dim Punkte As Point() = {}
        Dim Kreis(,) As Integer = Kreisfunktion(Reichweite)
        For X = 0 To Kreis.GetLength(0) - 1
            For Y = 0 To Kreis.GetLength(1) - 1
                If Kreis(X, Y) >= 0 Then
                    If Objektverwalter.Spielfeld.OnMap(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y) Then
                        If Not Objektverwalter.Spielfeld.Einheiten(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, Objektverwalter.Spielfeld.MomentaneSchlacht) Is Nothing Then
                            If Schaden > 0 Then
                                If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team Then
                                    Array.Resize(Punkte, Punkte.Length + 1)
                                    Punkte(Punkte.Length - 1) = New Point(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
                                End If
                            Else
                                If Spieler = Objektverwalter.Spielfeld.Einheiten(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler Then
                                    Array.Resize(Punkte, Punkte.Length + 1)
                                    Punkte(Punkte.Length - 1) = New Point(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
                                End If
                            End If
                        End If
                    End If
                End If
            Next
        Next
        Return Punkte
    End Function
    Protected Sub Geschuetzfeuermarkieren()
        Dim X As Integer = 1
        Dim XOrt As Integer = 0
        Dim YOrt As Integer = 0
        Select Case Angrifn
            Case Angriffe.SchussS
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt += 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussN
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt -= 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussW
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X - I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 -= 1
                        End If
                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussO
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X + I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 += 1
                        End If
                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
        End Select
    End Sub
    Protected Function GetGeschuetzfeuer() As Point()
        Dim Felder As New Stack(Of Point)
        Dim X As Integer = 1
        Dim XOrt As Integer = 0
        Dim YOrt As Integer = 0
        Select Case Angrifn
            Case Angriffe.SchussS
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt += 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        Dim P As New Point(Xort2, YOrt)
                        If Objektverwalter.Spielfeld.OnMap(P) Then
                            Felder.Push(P)
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussN
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt -= 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        Dim P As New Point(Xort2, YOrt)
                        If Objektverwalter.Spielfeld.OnMap(P) Then
                            Felder.Push(P)
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussW
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X - I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 -= 1
                        End If
                        Dim P As New Point(Xort2, YOrt)
                        If Objektverwalter.Spielfeld.OnMap(P) Then
                            Felder.Push(P)
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussO
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X + I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 += 1
                        End If
                        Dim P As New Point(Xort2, YOrt)
                        If Objektverwalter.Spielfeld.OnMap(P) Then
                            Felder.Push(P)
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
        End Select
        Return Felder.ToArray
    End Function
    ''' <summary>
    ''' Gibt alle Ziele von Geschuetzen zurueck.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GeschuetzZiele() As Point()
        Dim Punkte() As Point = {}
        Dim X As Integer = 1
        Dim XOrt As Integer = 0
        Dim YOrt As Integer = 0
        Select Case Angrifn
            Case Angriffe.SchussS
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt += 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Schaden > 0 Then
                                        If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    Else
                                        If Spieler = Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussN
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt -= 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Schaden > 0 Then
                                        If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    Else
                                        If Spieler = Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussW
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X - I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 -= 1
                        End If
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Schaden > 0 Then
                                        If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    Else
                                        If Spieler = Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussO
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X + I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 += 1
                        End If
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Schaden > 0 Then
                                        If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    Else
                                        If Spieler = Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler Then
                                            Array.Resize(Punkte, Punkte.Length + 1)
                                            Punkte(Punkte.Length - 1) = New Point(Xort2, YOrt)
                                        End If
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
        End Select
        Return Punkte
    End Function
    Protected Sub StrahlFeuerAnzeigen()
        For I As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X - I
            Dim Y As Integer = Rechteck.Y
            Objektverwalter.neuMarkiertesFeld(X, Y, Color.FromArgb(160, 255, 255, 255), "Rot")
        Next
        'Nach links markieren
        For I2 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X + I2
            Dim Y As Integer = Rechteck.Y
            Objektverwalter.neuMarkiertesFeld(X, Y, Color.FromArgb(160, 255, 255, 255), "Rot")
        Next
        'Nach oben markieren
        For I3 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y - I3
            Objektverwalter.neuMarkiertesFeld(X, Y, Color.FromArgb(160, 255, 255, 255), "Rot")
        Next
        'Nach unten markiern
        For I4 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y + I4
            Objektverwalter.neuMarkiertesFeld(X, Y, Color.FromArgb(160, 255, 255, 255), "Rot")
        Next
    End Sub
    Protected Function GetStrahlFeuerFelder() As Point()
        Dim Felder As New Stack(Of Point)
        For I As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X - I
            Dim Y As Integer = Rechteck.Y
            Dim P As New Point(X, Y)
            If Objektverwalter.Spielfeld.OnMap(P) Then
                Felder.Push(P)
            End If
        Next
        'Nach links markieren
        For I2 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X + I2
            Dim Y As Integer = Rechteck.Y
            Dim P As New Point(X, Y)
            If Objektverwalter.Spielfeld.OnMap(P) Then
                Felder.Push(P)
            End If
        Next
        'Nach oben markieren
        For I3 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y - I3
            Dim P As New Point(X, Y)
            If Objektverwalter.Spielfeld.OnMap(P) Then
                Felder.Push(P)
            End If
        Next
        'Nach unten markiern
        For I4 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y + I4
            Dim P As New Point(X, Y)
            If Objektverwalter.Spielfeld.OnMap(P) Then
                Felder.Push(P)
            End If
        Next
        Return Felder.ToArray
    End Function
    ''' <summary>
    ''' Gibt alle zu treffenden Einheiten zurueck.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function StrahlZieleZurueckgeben() As Point()
        Dim Punkte As Point() = {}
        'Nach Rechts markieren
        For I As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X - I
            Dim Y As Integer = Rechteck.Y
            If Not Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht) Is Nothing Then
                Array.Resize(Punkte, Punkte.Length + 1)
                Punkte(Punkte.Length - 1) = New Point(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
            End If
        Next
        'Nach links markieren
        For I2 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X + I2
            Dim Y As Integer = Rechteck.Y
            If Not Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht) Is Nothing Then
                Array.Resize(Punkte, Punkte.Length + 1)
                Punkte(Punkte.Length - 1) = New Point(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
            End If
        Next
        'Nach oben markieren
        For I3 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y - I3
            If Not Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht) Is Nothing Then
                Array.Resize(Punkte, Punkte.Length + 1)
                Punkte(Punkte.Length - 1) = New Point(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
            End If
        Next
        'Nach unten markiern
        For I4 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y + I4
            If Not Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht) Is Nothing Then
                Array.Resize(Punkte, Punkte.Length + 1)
                Punkte(Punkte.Length - 1) = New Point(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
            End If
        Next
        Return Punkte
    End Function
    Public MustOverride Sub Feuer(ByVal X As Integer, ByVal Y As Integer)
    Public Sub FeuerSchussMarkieren()
        Dim X As Integer = 1
        Dim XOrt As Integer = 0
        Dim YOrt As Integer = 0
        Select Case Angrifn
            Case Angriffe.SchussS
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt += 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Not Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team = Objektverwalter.Spielfeld.AktuellerSpieler.Team Then
                                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussN
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -I + Rechteck.Y
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            YOrt -= 1
                        End If
                        Dim Xort2 As Integer = Rechteck.X + XOrt
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Not Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team = Objektverwalter.Spielfeld.AktuellerSpieler.Team Then
                                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussW
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X - I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 -= 1
                        End If
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Not Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team = Objektverwalter.Spielfeld.AktuellerSpieler.Team Then
                                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
            Case Angriffe.SchussO
                For I As Integer = 1 To Reichweite
                    For I2 As Integer = 1 To X
                        YOrt = -XOrt + Rechteck.Y
                        Dim Xort2 As Integer = Rechteck.X + I
                        If Rechteck.Height = Hauptmenue.Feldbreite * 3 Then
                            Xort2 += 1
                        End If
                        If Objektverwalter.Spielfeld.OnMap(Xort2, YOrt) Then
                            If IsNothing(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                                If Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Sichtbar = True Then
                                    If Not Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(Xort2, YOrt, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler).Team = Objektverwalter.Spielfeld.AktuellerSpieler.Team Then
                                        Objektverwalter.neuMarkiertesFeld(Xort2, YOrt, Color.FromArgb(160, 255, 255, 255), "Rot")
                                    End If
                                End If
                            End If
                        End If
                        XOrt += 1
                    Next
                    X += 2
                    XOrt = 0
                    XOrt = XOrt - (X - 1) / 2
                Next
        End Select
    End Sub
    Protected Sub StrahlFeuer()
        BackbufferSpiel.AddAnimation("LASERSTRAHL", 0, New Point(Rechteck.X, Rechteck.Y), True, Schlacht)
        For I As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X - I
            Dim Y As Integer = Rechteck.Y
            DoDamage(X, Y)
        Next
        'Nach links markieren
        For I2 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X + I2
            Dim Y As Integer = Rechteck.Y
            DoDamage(X, Y)
        Next
        'Nach oben markieren
        For I3 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y - I3
            DoDamage(X, Y)
        Next
        'Nach unten markiern
        For I4 As Integer = 1 To Reichweite + 1
            Dim X As Integer = Rechteck.X
            Dim Y As Integer = Rechteck.Y + I4
            DoDamage(X, Y)
        Next
        'Jetzt muesste die Animation abgespielt werden

    End Sub

    Protected Sub KreisFeuer()
        Dim Kreis(,) As Integer = Kreisfunktion(Reichweite)
        For X = 0 To Kreis.GetLength(0) - 1
            For Y = 0 To Kreis.GetLength(1) - 1
                If Kreis(X, Y) > 0 Then
                    Heilung(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
                End If
            Next
        Next
    End Sub
    Protected Sub KreisFeuerAngriff()
        Dim Kreis(,) As Integer = Kreisfunktion(Reichweite)
        For X = 0 To Kreis.GetLength(0) - 1
            For Y = 0 To Kreis.GetLength(1) - 1
                If Kreis(X, Y) > 0 Then
                    If Objektverwalter.Spielfeld.OnMap(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y) Then
                        If IsNothing(Objektverwalter.Spielfeld.Einheiten(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                            If Objektverwalter.Spielfeld.Einheiten(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, Objektverwalter.Spielfeld.MomentaneSchlacht).GetSpieler.Team <> GetSpieler.Team Then
                                DoDamage(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y)
                            End If
                        End If
                    End If
                End If
            Next
        Next
    End Sub
    Protected Sub KugelFeuer()
        Dim Kreis(,) As Integer = Kreisfunktion(Reichweite)
        For X = 0 To Kreis.GetLength(0) - 1
            For Y = 0 To Kreis.GetLength(1) - 1
                If Kreis(X, Y) >= 0 Then
                    Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, ObjektSpielfeld.Bodenschlacht)
                    If IsNothing(E) = False Then
                        If E.GetSpieler.Team <> Me.GetSpieler.Team Then
                            DoDamage(Rechteck.X - Reichweite + X, Rechteck.Y - Reichweite + Y, ObjektSpielfeld.Bodenschlacht)
                        End If
                    End If
                End If
            Next
        Next
    End Sub

    ''' <summary>
    ''' Fuegt der Einheit Schaden Zu
    ''' </summary>
    ''' <param name="X"></param>
    ''' <param name="Y"></param>
    ''' <remarks></remarks>
    Public Sub Heilung(ByVal X As Integer, ByVal Y As Integer)
        If Objektverwalter.Spielfeld.OnMap(X, Y) Then
            If IsNothing(Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                If Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht).Spieler = Spieler Then
                    Dim KP As Integer = Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht).getKP - Schaden
                    If KP <= 0 Then
                        Objektverwalter.NeuObjektAnimation(X, Y)
                        Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht) = Nothing
                    Else
                        If KP > 10 Then
                            KP = 10
                        End If
                        Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht).Leben = KP * 10
                        If Schaden < 0 Then
                            Objektverwalter.Ration(X, Y, False, 4, Schlacht)
                        End If
                    End If
                End If
            End If
        End If
    End Sub
    Public Sub SiloZuenden(ByVal X As Integer, ByVal Y As Integer)
        If Angriff = Angriffe.Silo Or Angriff = Angriffe.Rakete Then
            Dim Kreis(,) As Integer = {}
            Select Case Reichweite
                Case 2
                    Kreis = Kreisfunktion(Reichweite)
                    Objektverwalter.NeuObjektAnimation(New Point(X, Y), "Explosion+Siloklein", Objektverwalter.Spielfeld.MomentaneSchlacht)
            End Select
            For X1 = 0 To Kreis.GetLength(0) - 1
                For Y1 = 0 To Kreis.GetLength(1) - 1
                    If Kreis(X1, Y1) >= 0 Then
                        If Objektverwalter.Spielfeld.OnMap(X - Reichweite + X1, Y - Reichweite + Y1) Then
                            DoDamage(X - Reichweite + X1, Y - Reichweite + Y1)
                        End If
                    End If
                Next
            Next
        End If
    End Sub
    Public Sub DoDamage(ByVal X As Integer, ByVal Y As Integer)
        If Objektverwalter.Spielfeld.OnMap(X, Y) Then
            If Not Objektverwalter.Spielfeld.Landschaften(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht).Hidden Then
                If IsNothing(Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht)) = False Then
                    Dim KP As Integer = Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht).getKP - Schaden
                    If KP <= 0 Then
                        If Objektverwalter.Spielfeld.Regeln.GebaeudeZerstoerung Then
                            Objektverwalter.NeuObjektAnimation(X, Y)
                            Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht) = Nothing
                        Else
                            Objektverwalter.Spielfeld.Einheiten(X, Y, Schlacht).Leben = 1
                        End If
                    Else
                        If KP > 10 Then
                            KP = 10
                        End If
                        Objektverwalter.Spielfeld.Einheiten(X, Y, Objektverwalter.Spielfeld.MomentaneSchlacht).Leben = KP * 10
                        If Schaden < 0 Then
                            Objektverwalter.Ration(X, Y, False, 0, Objektverwalter.Spielfeld.MomentaneSchlacht)
                        End If
                    End If
                End If
            End If
        End If
    End Sub
    Public Sub DoDamage(ByVal X As Integer, ByVal Y As Integer, ByVal Schlacht As Integer)
        If Objektverwalter.Spielfeld.OnMap(X, Y) Then
            If IsNothing(Objektverwalter.Spielfeld.Einheiten(X, Y, Schlacht)) = False Then
                Dim KP As Integer = Objektverwalter.Spielfeld.Einheiten(X, Y, Schlacht).getKP - Schaden
                If KP <= 0 Then
                    If Objektverwalter.Spielfeld.Regeln.GebaeudeZerstoerung Then
                        Objektverwalter.NeuObjektAnimation(X, Y)
                        Objektverwalter.Spielfeld.Einheiten(X, Y, Schlacht) = Nothing
                    Else
                        Objektverwalter.Spielfeld.Einheiten(X, Y, Schlacht).Leben = 1
                    End If
                Else
                    If KP > 10 Then
                        KP = 10
                    End If
                    Objektverwalter.Spielfeld.Einheiten(X, Y, Schlacht).Leben = KP * 10
                    If Schaden < 0 Then
                        Objektverwalter.Ration(X, Y, False, 0, Schlacht)
                    End If
                End If
            End If
        End If
    End Sub
    Public Function GetRealGebaeudeID() As String
        Return GebaeudeIDD
    End Function
    Protected Sub GenerateNetzBefehlGebaeudeFeuer(ByVal X As Integer, ByVal Y As Integer)

        If Objektverwalter.Spielfeld.AktuellerSpieler.KIStufe <> ObjektSpieler.KIStufen.Passiv Then
            Dim Befehl As New KINetzwerkBefehl
            Befehl.Befehl = ObjektKI.KIModiExtern.Schuss
            Befehl.KooX = Rechteck.X
            Befehl.KooY = Rechteck.Y
            Befehl.WegX = New Integer() {Rechteck.X}
            Befehl.WegY = New Integer() {Rechteck.Y}
            Befehl.OpferX = X
            Befehl.OpferY = Y
            Befehl.AngreiferSchaden = -1
            Befehl.Verteidigerschaden = -1
            Befehl.Spieler = Objektverwalter.Spielfeld.AktuellerSpieler.Spieler
            Hauptmenue.NetzBefehlSenden(Befehl)
        End If

    End Sub
    Public Function GetSpieler() As ObjektSpieler
        Return Objektverwalter.Spielfeld.Spieler(Spieler)
    End Function
    Public Overridable Function GetMaxLeben() As Integer
        Return 0
    End Function

#End Region

    ''' <summary>
    ''' Klont das gesamte Gebaeude
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim G As ObjektGebaeude = MemberwiseClone()
        ReDim G.Variablen(Variablen.Length - 1)
        For I = 0 To Variablen.Length - 1
            G.Variablen(I) = Variablen(I).Clone
        Next
        ReDim G.Verweisgebaeude(Verweisgebaeude.GetLength(0) - 1, Verweisgebaeude.GetLength(1) - 1)
        For X = 0 To Verweisgebaeude.GetLength(0) - 1
            For Y = 0 To Verweisgebaeude.GetLength(1) - 1
                G.Verweisgebaeude(X, Y) = Verweisgebaeude(X, Y)
            Next
        Next
        G.RotationsZenturm = New Point(RotationsZenturm.X, RotationsZenturm.Y)
        G.Rechteck = New Rectangle(Rechteck.X, Rechteck.Y, Rechteck.Width, Rechteck.Height)

        Return G
    End Function
    ''' <summary>
    ''' Gibt alle Einheiten zurueck die Seeeinheiten sind und Waffen haben und hier gebaut werden koennen!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSeaUnits(ByVal Prueffonds As Integer) As ObjektEinheit()
        Dim E As New Stack(Of ObjektEinheit)
        Dim L As String() = GetBauliste(Spieler)
        Dim S As ObjektSpieler = GetSpieler()
        For Each E1 In L
            Dim E2 As ObjektEinheit = ObjektLadeklasse.NewEinheit(E1, Spieler, Rechteck.X, Rechteck.Y)
            If E2.IsSeaUnit Then
                If E2.CanAttack Then
                    If E2.Kosten * S.Teurungsrate(E2, Rechteck.X, Rechteck.Y) <= Prueffonds Then
                        E.Push(E2)
                    End If
                End If
            End If
        Next
        Return E.ToArray
    End Function
    ''' <summary>
    ''' Gibt alle Einheiten zurueck die Bodeneinheiten sind und Waffen haben und hier gebaut werden koennen!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetGroundUnits(ByVal Prueffonds As Integer) As ObjektEinheit()
        Dim E As New Stack(Of ObjektEinheit)
        Dim L As String() = GetBauliste(Spieler)
        Dim S As ObjektSpieler = GetSpieler()
        For Each E1 In L
            Dim E2 As ObjektEinheit = ObjektLadeklasse.NewEinheit(E1, Spieler, Rechteck.X, Rechteck.Y)
            If E2.IsGroundUnit Then
                If E2.CanAttack Then
                    If E2.Kosten * S.Teurungsrate(E2, Rechteck.X, Rechteck.Y) <= Prueffonds Then
                        E.Push(E2)
                    End If
                End If
            End If
        Next
        Return E.ToArray
    End Function
    ''' <summary>
    ''' Gibt alle Einheiten zurueck die Lufteinheiten sind und Waffen haben und hier gebaut werden koennen!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetAirUnits(ByVal Prueffonds As Integer) As ObjektEinheit()
        Dim E As New Stack(Of ObjektEinheit)
        Dim L As String() = GetBauliste(Spieler)
        Dim S As ObjektSpieler = GetSpieler()
        For Each E1 In L
            Dim E2 As ObjektEinheit = ObjektLadeklasse.NewEinheit(E1, Spieler, Rechteck.X, Rechteck.Y)
            If E2.IsFlyingUnit Then
                If E2.CanAttack Then
                    If E2.Kosten * S.Teurungsrate(E2, Rechteck.X, Rechteck.Y) <= Prueffonds Then
                        E.Push(E2)
                    End If
                End If
            End If
        Next
        Return E.ToArray
    End Function
    Public Overridable Function IsAttackField(ByVal X As Integer, ByVal Y As Integer) As Boolean
        If GebaeudeIDD = "VERWEIS" Then
            Return Objektverwalter.Spielfeld.Landschaften(Rechteck.X, Rechteck.Y, Objektverwalter.Spielfeld.MomentaneSchlacht).Gebaeude.IsAttackField(X, Y)
        Else
            X -= Rechteck.X
            Y -= Rechteck.Y
            If X = 0 And Y = 0 Then Return True
            For I = 0 To Verweisgebaeude.GetLength(0) - 1
                If Verweisgebaeude(I, 0) = X And Verweisgebaeude(I, 1) = Y Then
                    Return True
                End If
            Next
        End If
        Return False
    End Function
End Class
